package com.jsy.mydbutil;

import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.text.TextUtils;

import java.lang.reflect.Field;
import java.util.List;

public abstract class MyDataBase extends SQLiteOpenHelper {

    public class TableBean {
        public Class c;
        public String tableName;

        public TableBean(Class c, String tableName) {
            this.c = c;
            this.tableName = tableName;
        }
    }

    public final List<TableBean> tablesList = initTablesList();


    public MyDataBase(Context context, String dbName, SQLiteDatabase.CursorFactory factory, int version) {
        super(context, dbName, factory, version);
    }


    /**
     * 初始化要创建的表名
     */
    public abstract List<TableBean> initTablesList();


    @Override
    public void onCreate(SQLiteDatabase db) {
        for (TableBean tb : tablesList) {
            MyDbUtil.createTable(tb.c, tb.tableName, db);
        }
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        for (TableBean tb : tablesList) {
            //表存在
            if (tableIsExist(tb.tableName,db)) {
                checkTableUpdate(tb, db);
            } else {
                //表不存在
                MyDbUtil.createTable(tb.c, tb.tableName, db);
            }

        }
    }

    /**
     * 检测一个数据库表的字段缺失，并给它添加缺失的字段
     *
     * @param tb
     */
    private void checkTableUpdate(TableBean tb, SQLiteDatabase db) {
        Cursor c = db.rawQuery("SELECT * FROM " + tb.tableName + " WHERE 0", null);
        try {
            String[] oldColumnNames = c.getColumnNames();
            Field[] declaredFields = tb.c.getDeclaredFields();
            for (Field field : declaredFields) {
                // 获取Field上的注解,只有写了注释的字段才表示要存到表中
                DbProperty dbProperty = field.getAnnotation(DbProperty.class);
                //只有写了注释的字段才表示要存到表中
                if (dbProperty != null) {
                    boolean exist = false;
                    for (String oldName : oldColumnNames) {
                        if (oldName.toLowerCase().equals(field.getName().toLowerCase())){
                            //字段名已存在的不需要处理
                            exist = true;
                            break;
                        }
                    }
                    if (exist){
                        continue;
                    }else {
                        //获取类型
                        String type = "TEXT";
                        Class fieldClass = field.getType();
                        if (fieldClass == int.class || fieldClass == Integer.class || fieldClass == long.class || fieldClass == Long.class) {
                            type = "INTEGER";
                        }
                        if (field.getType() == float.class || field.getType() == Float.class || field.getType() == double.class || field.getType() == Double.class) {
                            type = "REAL";
                        }
                        // 获取注解值
                        String property = "";
                        String[] propertys = dbProperty.property();
                        for (String string : propertys) {
                            property += string;
                            property += " ";
                        }

                        String defaultValue = dbProperty.defaultValue();
                        if (!TextUtils.isEmpty(defaultValue)) {
                            defaultValue = " default " + defaultValue + " ";
                        }

                        String sql = "ALTER TABLE "+tb.tableName+" ADD "+field.getName()+" "+type+" "+property+" "+defaultValue;
                        db.execSQL(sql);
                    }
                }

            }
        } finally {
            c.close();
        }
    }


    /**
     * 判断某张表是否存在
     *
     * @param tableName 表名
     * @return
     */
    public boolean tableIsExist(String tableName,SQLiteDatabase db) {
        boolean result = false;
        if (tableName == null) {
            return false;
        }
        Cursor cursor = null;
        try {
            String sql = "select count(*) as c from Sqlite_master where type = 'table' and name = '" + tableName.trim() + "' ";
            cursor = db.rawQuery(sql, null);
            if (cursor.moveToNext()) {
                int count = cursor.getInt(0);
                if (count > 0) {
                    result = true;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }
}
